package it.nard.controller;

import it.nard.persistence.model.Latteinentrata;
import it.nard.persistence.model.Rmozzarella;
import it.nard.persistence.model.Rprovola;
import it.nard.persistence.model.Rricotta;
import it.nard.sourceframes.AnalisiLattePnl;
import it.nard.sourceframes.AnalisiProduzionePnl;
import it.nard.sourceframes.MainFrame;
import it.nard.utils.GraphElemComparator;
import it.nard.utils.GraphElement;
import it.nard.utils.TimeSlots;

import java.awt.event.MouseEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.ButtonGroup;

import org.jfree.chart.ChartColor;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.joda.time.DateTime;

public class AnalisiProduzioneController  extends BasicController{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6729316031073309352L;

	public static final int GRAPH_PERIOD_DAYS = 0;

	public static final int GRAPH_PERIOD_WEEKS = 1;
	
	public static final int GRAPH_PERIOD_MONTHS = 2;



	
	public AnalisiProduzioneController(){
		super("Analisi Produzione", null);
	
	}
	
	
	
	
	public void select (MouseEvent mevent){
		
	
	}
	
	
	
	public void onDateSelect(){
	
		mainFrame.sendMessage("Creazione Analisi Produzione", MainFrame.OK_MESSAGE);
		Date firstDate = ((AnalisiProduzionePnl)controlPnl).getJXDatePicker0().getDate();
		Date secondDate = ((AnalisiProduzionePnl)controlPnl).getJXDatePicker1().getDate();
	
		if(firstDate.compareTo(secondDate)>=0){
			return;
		}
		
		boolean mozzarellaSelected =  ((AnalisiProduzionePnl)controlPnl).getJCheckBox0().isSelected();
		boolean provolaSelected =  ((AnalisiProduzionePnl)controlPnl).getJCheckBox1().isSelected();
		boolean ricottaSelected =  ((AnalisiProduzionePnl)controlPnl).getJCheckBox2().isSelected();
		
		int period = GRAPH_PERIOD_DAYS;
		if( ((AnalisiProduzionePnl)controlPnl).getJRadioButton1().isSelected()){
			period = GRAPH_PERIOD_WEEKS;
		}
		else if( ((AnalisiProduzionePnl)controlPnl).getJRadioButton2().isSelected()){
			period = GRAPH_PERIOD_MONTHS;
		}
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		
	
		ArrayList<GraphElement> graphElemList = new ArrayList<GraphElement>();
		if(mozzarellaSelected){
			graphElemList.addAll(this.graph4Latte("Mozzarella", 
						this.createSlotsMozzarella(MainController.getRMozzarellaController().retriveListFromDates(firstDate, secondDate)),
						firstDate,  secondDate, period));
		}
		if(provolaSelected){
			graphElemList.addAll(this.graph4Latte("Provola", 
					this.createSlotsProvola(MainController.getRProvolaController().retriveListFromDates(firstDate, secondDate)),
					firstDate,  secondDate, period));
		}
		if(ricottaSelected){
			graphElemList.addAll(this.graph4Latte("Ricotta", 
					this.createSlotsRicotta(MainController.getRRicottaController().retriveListFromDates(firstDate, secondDate)),
					firstDate,  secondDate, period));
		}

		
		Collections.sort(graphElemList, new GraphElemComparator());
		this.composeDataSet(dataset, graphElemList);
//	
		
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		
        JFreeChart chart = ChartFactory.createBarChart3D( "Analisi periodo "+sdf.format(firstDate)+"-"+sdf.format(secondDate), 
        "Mozzarella/Provola/Ricotta", "Totale (Kg.)", dataset, PlotOrientation.VERTICAL, true, true, false );
        
        ((AnalisiProduzionePnl)controlPnl).getJPanel1().setChart(chart);
        
        CategoryPlot plot = (CategoryPlot)chart.getPlot();
        CategoryAxis xAxis = (CategoryAxis)plot.getDomainAxis();
        xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
 
        chart.setBackgroundPaint(ChartColor.WHITE);

	}
	
	private HashMap<Integer, TimeSlots> associateDate2Ts(Set<Integer> dates, ArrayList<TimeSlots> as){
		HashMap<Integer, TimeSlots>  matching = new HashMap<Integer, TimeSlots>();
		Iterator<Integer> iter = dates.iterator();
		while(iter.hasNext()){
			Integer dateIn = iter.next();
			Iterator<TimeSlots> iterTs = as.iterator();
			while(iterTs.hasNext()){
				TimeSlots ts = iterTs.next();
				if(ts.startDate<=dateIn && ts.endDate>dateIn){
					matching.put(dateIn, ts);
				}
			}
		}
		return matching;
	}
	private void composeDataSet(DefaultCategoryDataset dataset, ArrayList<GraphElement> ge){
		Iterator<GraphElement> iter = ge.iterator();
		while(iter.hasNext()){
			GraphElement elem = iter.next();
			dataset.addValue(elem.value, elem.row, elem.column);
		}
		
		
	}
	
	
	private ArrayList<TimeSlots> createKeyList(Date dt1, Date dt2, int graphPeriod ){
		 ArrayList<TimeSlots> out = new ArrayList<TimeSlots>();
		 DateTime dtOrg = new DateTime(dt1);
		 TimeSlots elem = new TimeSlots();
		 elem.startDate = Integer.valueOf(SDF_4_DB.format(dt1));
		 while(dtOrg.toDate().compareTo(dt2)<0){
			
			 if(graphPeriod==GRAPH_PERIOD_DAYS)
				 dtOrg = dtOrg.plusDays(1);
			 else if(graphPeriod==GRAPH_PERIOD_WEEKS)
				 dtOrg = dtOrg.plusWeeks(1);
			 else if(graphPeriod==GRAPH_PERIOD_MONTHS)
				 dtOrg = dtOrg.plusMonths(1);

			 elem.endDate = Integer.valueOf(SDF_4_DB.format(dtOrg.toDate()));
			 
			 out.add(elem);
			 elem = new TimeSlots();
			 elem.startDate = Integer.valueOf(SDF_4_DB.format(dtOrg.toDate()));
		 }
		 return out;
	}
	
	
	
	
	
	
	public void delete (){
		
	}
	
	public void insert (){
		
	}
	
	public AnalisiProduzionePnl getMainPanel(){
		
			
		if( controlPnl==null){
			 controlPnl = new  AnalisiProduzionePnl(this);

			 ButtonGroup bg = new ButtonGroup();
			 bg.add(((AnalisiProduzionePnl)controlPnl).getJRadioButton0());
			 bg.add(((AnalisiProduzionePnl)controlPnl).getJRadioButton1());
			 bg.add(((AnalisiProduzionePnl)controlPnl).getJRadioButton2());
				
		}
		return  ((AnalisiProduzionePnl)controlPnl);
	}

	
	private ArrayList<GraphElement> graph4Latte(String graphString, HashMap<Integer, Double> totals, Date dt1, Date dt2, int graphPeriod){
		
		ArrayList<GraphElement> out = new ArrayList<GraphElement>();
		
		ArrayList<TimeSlots> ts = this.createKeyList(dt1, dt2, graphPeriod);
		
	
		HashMap<Integer, TimeSlots> matching = this.associateDate2Ts(totals.keySet(), ts);
		
		
		Iterator<Integer> iter = matching.keySet().iterator();
		while(iter.hasNext()){
			Integer dateIn = iter.next();
			TimeSlots tsElem =  matching.get(dateIn);
			Double totalsElem = totals.get(dateIn);
			
			
			GraphElement gE = new GraphElement();
			gE.dateValue = tsElem.startDate;
			if(out.contains(gE)){
				gE = out.get(out.indexOf(gE));
			}
			gE.row   = graphString;
			gE.column= tsElem.getLabelString();
			gE.value = gE.value+ totalsElem;
			
			out.add(gE);
		}
		
		return out;
	}

	
	private HashMap<Integer, Double> createSlotsMozzarella (List<Rmozzarella> in){
		HashMap<Integer, Double> out = new HashMap<Integer,Double>();
		
		Iterator<Rmozzarella> iter = in.iterator();
		while(iter.hasNext()){
			Rmozzarella elem = iter.next();
			if(out.get(elem.getDataproduzione())==null)
				out.put(elem.getDataproduzione(), new Double(0d));
				
				out.put(elem.getDataproduzione(),out.get(elem.getDataproduzione())+elem.getTotal());
			
		}
		return out;
	}
	
	private HashMap<Integer, Double> createSlotsProvola (List<Rprovola> in){
		HashMap<Integer, Double> out = new HashMap<Integer,Double>();
		
		Iterator<Rprovola> iter = in.iterator();
		while(iter.hasNext()){
			Rprovola elem = iter.next();
			if(out.get(elem.getDataproduzione())==null)
				out.put(elem.getDataproduzione(), new Double(0d));
				
				out.put(elem.getDataproduzione(),out.get(elem.getDataproduzione())+elem.getTotal());
			
		}
		return out;
	}
	
	private HashMap<Integer, Double> createSlotsRicotta (List<Rricotta> in){
		HashMap<Integer, Double> out = new HashMap<Integer,Double>();
		
		Iterator<Rricotta> iter = in.iterator();
		while(iter.hasNext()){
			Rricotta elem = iter.next();
			if(out.get(elem.getDataproduzione())==null)
				out.put(elem.getDataproduzione(), new Double(0d));
				
				out.put(elem.getDataproduzione(),out.get(elem.getDataproduzione())+ Double.parseDouble(elem.getTotale()));
			
		}
		return out;
	}
	
	@Override
	public String getControllerCode() {
		return null;
	}

	@Override
	public void clearPnl() {
		
	}
	

	
	
	
	
	
}

